package templatemanager

import (
	"context"
	"errors"

	"dev.ixmxm.top/rms/boot"
	"dev.ixmxm.top/rms/codes"
	"dev.ixmxm.top/rms/model"
	"dev.ixmxm.top/rms/utils/function"
	"dev.ixmxm.top/rms/utils/log"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

//初始化任务模板对象
func NewTemplateManager(db *boot.MongoDB) *TemplateManager {
	ttm := &TemplateManager{db: db}
	return ttm
}

type TemplateManager struct {
	db           *boot.MongoDB
	SystemConfig *model.SystemConfig //系统配置(缓存),不可直接赋值保存，调用SaveSystemConfigToCache保存
}

//保存任务模板
func (ttm *TemplateManager) SaveTaskTemplate(ctx context.Context, taskTemplate *model.TaskTemplate) codes.Code {
	dbRes := ttm.db.Collection(ctx, model.TaskTemplate{}.TableName()).FindOneAndReplace(ctx, bson.M{"id": taskTemplate.Id}, taskTemplate, &options.FindOneAndReplaceOptions{Upsert: function.BoolPtr(true)})
	if dbRes.Err() != nil && !errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		log.ErrorfWithContext(ctx, "保存任务模板 error:%s", dbRes.Err().Error())
		return codes.ErrDatabase.Wrap(dbRes.Err())
	}
	return nil
}

//保存子任务模板
func (ttm *TemplateManager) SaveTaskItemTemplate(ctx context.Context, taskItemTemplate *model.TaskItemTemplate) codes.Code {
	dbRes := ttm.db.Collection(ctx, model.TaskItemTemplate{}.TableName()).FindOneAndReplace(ctx, bson.M{"index": taskItemTemplate.Index, "task_template_id": taskItemTemplate.TaskTemplateId}, taskItemTemplate, &options.FindOneAndReplaceOptions{Upsert: function.BoolPtr(true)})
	if dbRes.Err() != nil && !errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		log.ErrorfWithContext(ctx, "保存子任务模板 error:%s", dbRes.Err().Error())
		return codes.ErrDatabase.Wrap(dbRes.Err())
	}
	return nil
}

//批量插入子任务模板集合
func (ttm *TemplateManager) SaveTaskItemTemplateList(ctx context.Context, taskItemTemplatelist []model.TaskItemTemplate, taskTemplateId int) codes.Code {
	log.Infof("主模板编号：%d , 开始批量添加所有子模板", taskTemplateId)
	if len(taskItemTemplatelist) == 0 {
		return codes.ErrSubtaskTemplateIsNull
	}
	ctxTx := boot.Begin(ctx)
	//1.先删除所有的机器人配置数据
	_, err := ttm.db.Collection(ctxTx, model.TaskItemTemplate{}.TableName()).DeleteMany(ctx, bson.M{"task_template_id": taskTemplateId})
	if err != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "clear all subtask template from db. error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}
	var tList []interface{}
	for _, subtaskTemplate := range taskItemTemplatelist {
		tList = append(tList, subtaskTemplate)
	}
	//2.插入所有子任务模板
	_, err2 := ttm.db.Collection(ctxTx, model.TaskItemTemplate{}.TableName()).InsertMany(ctxTx, tList)
	if err2 != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "insert many subtask template to db. error:%s", err2.Error())
		return codes.ErrDatabase.Wrap(err2)
	}
	ctxTx.Commit()
	return nil
}

//删除任务模板
func (ttm *TemplateManager) DeleteTaskTemplate(ctx context.Context, id int) codes.Code {
	err1 := ttm.DeleteTaskItemTemplates(ctx, id)
	if err1 != nil {
		return err1
	}

	_, err := ttm.db.Collection(ctx, model.TaskTemplate{}.TableName()).DeleteOne(ctx, bson.M{"id": id})
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		log.ErrorfWithContext(ctx, "delete charge site from db error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}
	return nil
}

//删除一条子任务模板
func (ttm *TemplateManager) DeleteTaskItemTemplate(ctx context.Context, taskTemplateId, index int) codes.Code {
	_, err := ttm.db.Collection(ctx, model.TaskItemTemplate{}.TableName()).DeleteOne(ctx, bson.M{"task_template_id": taskTemplateId, "index": index})
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		log.ErrorfWithContext(ctx, "delete charge site from db error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}
	return nil
}

//删除多条子任务模板
func (ttm *TemplateManager) DeleteTaskItemTemplates(ctx context.Context, taskTemplateId int) codes.Code {
	_, err := ttm.db.Collection(ctx, model.TaskItemTemplate{}.TableName()).DeleteMany(ctx, bson.M{"task_template_id": taskTemplateId})
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		log.ErrorfWithContext(ctx, "delete charge site from db error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}
	return nil
}

//获取所有任务模板
func (ttm *TemplateManager) GetAllTaskTemplates(ctx context.Context) ([]*model.TaskTemplate, codes.Code) {
	dbRes, err := ttm.db.Collection(ctx, model.TaskTemplate{}.TableName()).Find(ctx, bson.M{})
	if err != nil {
		log.ErrorfWithContext(ctx, "get all waiting tasks from db error:%s", err.Error())
		return nil, codes.ErrDatabase.Wrap(err)
	}
	taskTemplates := make([]*model.TaskTemplate, 0)
	if errBind := dbRes.All(ctx, &taskTemplates); errBind != nil {
		log.ErrorfWithContext(ctx, "bind all waiting tasks from db error:%s", errBind.Error())
		return nil, codes.ErrDatabase.Wrap(errBind)
	}
	return taskTemplates, nil
}

//根据小车子类型编号和任务类型获取任务模板
func (ttm *TemplateManager) GetTaskTemplate(ctx context.Context, categoryId int, taskType model.TaskType) (*model.TaskTemplate, codes.Code) {
	dbRes := ttm.db.Collection(ctx, model.TaskTemplate{}.TableName()).FindOne(ctx, bson.M{"category_id": categoryId, "task_type": taskType})
	if dbRes.Err() != nil && !errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		log.Errorf("根据任务模板ID获取任务模板失败 categoryId:%d  taskType:%s  error:%s", categoryId, taskType, dbRes.Err().Error())
		return nil, codes.ErrDatabase.Wrap(dbRes.Err())
	}
	if dbRes.Err() != nil && errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		//log.Errorf("can not find task:%d",id)
		return nil, nil
	}
	taskTemplate := new(model.TaskTemplate)
	if errBind := dbRes.Decode(taskTemplate); errBind != nil {
		log.Errorf("根据任务模板ID获取任务模板失败 categoryId:%d  taskType:%s  error:%s", categoryId, taskType, dbRes.Err().Error())
		return nil, codes.ErrDatabase.Wrap(errBind)
	}
	return taskTemplate, nil
}

//根据任务模板ID获取任务模板
func (ttm *TemplateManager) GetTaskTemplate2(ctx context.Context, taskTemplateId uint) (*model.TaskTemplate, codes.Code) {
	dbRes := ttm.db.Collection(ctx, model.TaskTemplate{}.TableName()).FindOne(ctx, bson.M{"id": taskTemplateId})
	if dbRes.Err() != nil && !errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		log.Errorf("根据任务模板ID获取任务模板失败 taskTemplateId:%d   error:%s", taskTemplateId, dbRes.Err().Error())
		return nil, codes.ErrDatabase.Wrap(dbRes.Err())
	}
	if dbRes.Err() != nil && errors.Is(dbRes.Err(), mongo.ErrNoDocuments) {
		//log.Errorf("can not find task:%d",id)
		return nil, codes.ErrTaskNotExists
	}
	taskTemplate := new(model.TaskTemplate)
	if errBind := dbRes.Decode(taskTemplate); errBind != nil {
		log.Errorf("根据任务模板ID获取任务模板失败 taskTemplateId:%d   error:%s", taskTemplateId, errBind.Error())
		return nil, codes.ErrDatabase.Wrap(errBind)
	}
	return taskTemplate, nil
}

//导入所有的任务模板
func (ttm *TemplateManager) ImportAllTaskTemplates(ctx context.Context, allTaskTemplate []interface{}) codes.Code {
	log.Infof("开始清空所有子任务模板数据，并且将excel数据导入所有子任务模板数据")
	ctxTx := boot.Begin(ctx)
	//1.先删除所有字幕版配置
	_, err := ttm.db.Collection(ctxTx, model.TaskTemplate{}.TableName()).DeleteMany(ctxTx, bson.D{})
	if err != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "clear all subTaskTemplate from db. error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}

	//2.插入所有的AGV类型
	_, err2 := ttm.db.Collection(ctxTx, model.TaskTemplate{}.TableName()).InsertMany(ctx, allTaskTemplate)
	if err2 != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "insert all subTaskTemplate to db. error:%s", err2.Error())
		return codes.ErrDatabase.Wrap(err2)
	}
	ctxTx.Commit()
	return nil
}

//导入所有的子任务模板 ImportAllSubtaskTemplates
func (ttm *TemplateManager) ImportAllSubtaskTemplates(ctx context.Context, allSubTaskTemplate []interface{}) codes.Code {
	log.Infof("开始清空所有子任务模板数据，并且将excel数据导入所有子任务模板数据")
	ctxTx := boot.Begin(ctx)
	//1.先删除所有字幕版配置
	_, err := ttm.db.Collection(ctxTx, model.TaskItemTemplate{}.TableName()).DeleteMany(ctxTx, bson.D{})
	if err != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "clear all subTaskTemplate from db. error:%s", err.Error())
		return codes.ErrDatabase.Wrap(err)
	}

	//2.插入所有的AGV类型
	_, err2 := ttm.db.Collection(ctxTx, model.TaskItemTemplate{}.TableName()).InsertMany(ctxTx, allSubTaskTemplate)
	if err2 != nil {
		ctxTx.Rollback()
		log.ErrorfWithContext(ctx, "insert all subTaskTemplate to db. error:%s", err2.Error())
		return codes.ErrDatabase.Wrap(err2)
	}
	ctxTx.Commit()
	return nil
}

//获取子任务模板
func (ttm *TemplateManager) GetTaskItemTemplates(ctx context.Context, taskTemplateId int) ([]*model.TaskItemTemplate, codes.Code) {
	dbRes, err := ttm.db.Collection(ctx, model.TaskItemTemplate{}.TableName()).Find(ctx, bson.M{"task_template_id": taskTemplateId}, &options.FindOptions{Sort: bson.M{"index": 1}})
	if err != nil {
		log.ErrorfWithContext(ctx, "get all waiting tasks from db error:%s", err.Error())
		return nil, codes.ErrDatabase.Wrap(err)
	}
	taskItemTemplates := make([]*model.TaskItemTemplate, 0)
	if errBind := dbRes.All(ctx, &taskItemTemplates); errBind != nil {
		log.ErrorfWithContext(ctx, "bind all waiting tasks from db error:%s", errBind.Error())
		return nil, codes.ErrDatabase.Wrap(errBind)
	}
	return taskItemTemplates, nil
}

//获取所有子任务
func (ttm *TemplateManager) GetTaskExportItemTemplates(ctx context.Context) ([]*model.TaskItemTemplate, codes.Code) {
	dbRes, err := ttm.db.Collection(ctx, model.TaskItemTemplate{}.TableName()).Find(ctx, bson.D{})
	if err != nil {
		log.ErrorfWithContext(ctx, "get all waiting tasks from db error:%s", err.Error())
		return nil, codes.ErrDatabase.Wrap(err)
	}
	taskItemTemplates := make([]*model.TaskItemTemplate, 0)
	if errBind := dbRes.All(ctx, &taskItemTemplates); errBind != nil {
		log.ErrorfWithContext(ctx, "bind all waiting tasks from db error:%s", errBind.Error())
		return nil, codes.ErrDatabase.Wrap(errBind)
	}
	return taskItemTemplates, nil
}
